package io.kiki.sba.registry.common.model.console;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang.StringUtils;

import java.util.HashSet;
import java.util.Set;

@JsonIgnoreProperties(ignoreUnknown = true)
public class CircuitBreakerData {


    @Setter
    @JsonInclude(Include.NON_NULL)
    private Boolean addressSwitch;


    @Getter
    private Set<String> overflowAddress = new HashSet<>();


    @Setter
    @Getter
    private Set<String> address = new HashSet<>();

    public CircuitBreakerData() {
    }

    public CircuitBreakerData(Boolean addressSwitch, Set<String> address) {
        this.addressSwitch = addressSwitch;
        this.address = address;
    }

    public CircuitBreakerData(Boolean addressSwitch, Set<String> overflowAddress, Set<String> address) {
        this.addressSwitch = addressSwitch;
        this.overflowAddress = overflowAddress;
        this.address = address;
    }

    public Boolean isAddressSwitch() {
        return addressSwitch;
    }

    public void add(CircuitBreakOption option, Set<String> ips) {
        switch (option) {
        case overflow:
            overflowAddress.addAll(ips);
            break;
        case stop_push:
            address.addAll(ips);
            break;
        default:
            throw new IllegalArgumentException("invalid option: " + option);
        }
    }

    public void remove(CircuitBreakOption option, Set<String> ips) {
        switch (option) {
        case overflow:
            overflowAddress.removeAll(ips);
            break;
        case stop_push:
            address.removeAll(ips);
            break;
        default:
            throw new IllegalArgumentException("invalid option: " + option);
        }
    }

    public boolean addressSwitch(boolean defaultValue) {
        return addressSwitch == null ? defaultValue : addressSwitch;
    }


    public enum CircuitBreakOption {
        overflow("overflow"), stop_push("stopPush"),
        ;

        String option;

        CircuitBreakOption(String option) {
            this.option = option;
        }

        public static CircuitBreakOption getByOption(String option) {
            if (StringUtils.isBlank(option)) {
                return null;
            }
            for (CircuitBreakOption value : CircuitBreakOption.values()) {
                if (StringUtils.equalsIgnoreCase(value.option, option)) {
                    return value;
                }
            }
            return null;
        }


        public String getOption() {
            return option;
        }
    }
}
